25 research outputs found

    An Equational Theory for Weak Bisimulation via Generalized Parameterized Coinduction

    Full text link
    Coinductive reasoning about infinitary structures such as streams is widely applicable. However, practical frameworks for developing coinductive proofs and finding reasoning principles that help structure such proofs remain a challenge, especially in the context of machine-checked formalization. This paper gives a novel presentation of an equational theory for reasoning about structures up to weak bisimulation. The theory is both compositional, making it suitable for defining general-purpose lemmas, and also incremental, meaning that the bisimulation can be created interactively. To prove the theory's soundness, this paper also introduces generalized parameterized coinduction, which addresses expressivity problems of earlier works and provides a practical framework for coinductive reasoning. The paper presents the resulting equational theory for streams, but the technique applies to other structures too. All of the results in this paper have been proved in Coq, and the generalized parameterized coinduction framework is available as a Coq library.Comment: To be published in CPP 202

    Interaction Trees: Representing Recursive and Impure Programs in Coq

    Get PDF
    "Interaction trees" (ITrees) are a general-purpose data structure for representing the behaviors of recursive programs that interact with their environments. A coinductive variant of "free monads," ITrees are built out of uninterpreted events and their continuations. They support compositional construction of interpreters from "event handlers", which give meaning to events by defining their semantics as monadic actions. ITrees are expressive enough to represent impure and potentially nonterminating, mutually recursive computations, while admitting a rich equational theory of equivalence up to weak bisimulation. In contrast to other approaches such as relationally specified operational semantics, ITrees are executable via code extraction, making them suitable for debugging, testing, and implementing software artifacts that are amenable to formal verification. We have implemented ITrees and their associated theory as a Coq library, mechanizing classic domain- and category-theoretic results about program semantics, iteration, monadic structures, and equational reasoning. Although the internals of the library rely heavily on coinductive proofs, the interface hides these details so that clients can use and reason about ITrees without explicit use of Coq's coinduction tactics. To showcase the utility of our theory, we prove the termination-sensitive correctness of a compiler from a simple imperative source language to an assembly-like target whose meanings are given in an ITree-based denotational semantics. Unlike previous results using operational techniques, our bisimulation proof follows straightforwardly by structural induction and elementary rewriting via an equational theory of combinators for control-flow graphs.Comment: 28 pages, 4 pages references, published at POPL 202

    33Úmes Journées Francophones des Langages Applicatifs

    Get PDF
    International audienceLes 33Ăšmes JournĂ©es Francophones des Langages Applicatifs (JFLA) se sont tenues Ă  Saint-MĂ©dard-d'Excideuil, plus prĂ©cisĂ©ment Domaine d'EssendiĂ©ras (PĂ©rigord), du mardi 28 juin 2022 au vendredi 1er juillet 2022.Les JFLA rĂ©unissent concepteurs, utilisateurs et thĂ©oriciens ; elles ont pour ambition de couvrir les domaines des langages applicatifs, de la preuve formelle, de la vĂ©rification de programmes, et des objets mathĂ©matiques qui sous-tendent ces outils. Ces domaines doivent ĂȘtre pris au sens large : nous souhaitons promouvoir les ponts entre les diffĂ©rentes thĂ©matiques.- Langages fonctionnels et applicatifs : sĂ©mantique, compilation, optimisation, typage, mesures, extensions par d'autres paradigmes.- Assistants de preuve : implĂ©mentation, nouvelles tactiques, dĂ©veloppements prĂ©sentant un intĂ©rĂȘt technique ou mĂ©thodologique.- Logique, correspondance de Curry-Howard, rĂ©alisabilitĂ©, extraction de programmes, modĂšles.- SpĂ©cification, prototypage, dĂ©veloppements formels d'algorithmes.- VĂ©rification de programmes ou de modĂšles, mĂ©thode dĂ©ductive, interprĂ©tation abstraite, raffinement.- Utilisation industrielle des langages fonctionnels et applicatifs, ou des mĂ©thodes issues des preuves formelles, outils pour le web.Les articles soumis aux JFLA sont relus par au moins deux personnes s'ils sont acceptĂ©s, trois personnes s'ils sont rejetĂ©s. Les critiques des relecteurs sont toujours bienveillantes et la plupart du temps encourageantes et constructives, mĂȘme en cas de rejet

    Generation of polynomial inequalities as invariants

    No full text
    Embedded software in critical systems rise a need for software analysis, especially for guaranteeing safety properties. In the late seventies, Cousot & Cousot introduced a general framework, called abstract interpretation, dedicated to the conception of particular analyses: static analyses. Among the program properties of interest, discovering algebraic relationships between variables allows for proving the lack of run-time errors. While the inference of linear relationships is e fficiently solved, computing polynomial equalities as invariants is still a challenge, a fortiori is the inequality counterpart. After a brief overview of existing techniques for invariant inference, this report investigates the viability of a constraint-based method dedicated to the inference of polynomial inequalities as program invariants

    VĂ©rification d'un glaneur de cellules concurrent

    Get PDF
    Modern compilers are complex programs, performing several heuristic-based optimisations. As such, and despite extensive testing, they may contain bugs leading to the introduction of new behaviours in the compiled program.To address this issue, we are nowadays able to prove correct, in proof assistants such as Coq, optimising compilers for languages such as C or ML. To date, a similar result for high-level languages such as Java nonetheless remain out of reach. Such languages indeed possess two essential characteristics: concurrency and a particularly complex runtime.This thesis aims at reducing the gap toward the implementation of such a verified compiler. To do so, we focus more specifically on a state-of-the-art concurrent garbage collector. This component of the runtime takes care of automatically reclaiming memory during the execution to remove this burden from the developer side. In order to keep the induced overhead as low as possible, the garbage collector needs to be extremely efficient. More specifically, the algorithm considered is said to be ``on the fly'': by relying on fine-grained concurrency, the user-threads are never caused to actively wait. The key property we establish is the functional correctness of this garbage collector, i.e. that a cell that a user thread may still access is never reclaimed.We present in a first phase the algorithm considered and its formalisation in Coq by implementing it in a dedicated intermediate representation. We introduce the proof system we used to conduct the proof, a variant based on the well-established Rely-Guarantee logic, and prove the algorithm correct.Reasoning simultaneously over both the garbage collection algorithm itself and the implementation of the concurrent data-structures it uses would entail an undesired additional complexity. The proof is therefore conducted with respect to abstract operations: they take place instantaneously. To justify this simplification, we introduce in a second phase a methodology inspired by the work of Vafeiadis and dedicated to the proof of observational refinement for so-called ``linearisable'' concurrent data-structures. We provide the approach with solid semantic foundations, formalised in Coq. This methodology is instantiated to soundly implement the main data-structure used in our garbage collector.Les compilateurs modernes constituent des programmes complexes, rĂ©alisant de nombreuses optimisations afin d'amĂ©liorer la performance du code gĂ©nĂ©rĂ©. Du fait de cette complexitĂ©, des bugs y sont rĂ©guliĂšrement dĂ©tectĂ©, conduisant Ă  l'introduction de nouveau comportement dans le programme compilĂ©. En rĂ©action, il est aujourd'hui possible de prouver correct, dans des assistants de preuve tels que Coq, des compilateurs optimisants pour des langages tels que le C ou ML. Transporter un tel rĂ©sultat pour des langages haut-niveau tels que Java est nĂ©anmoins encore hors de portĂ©e de l'Ă©tat de l'art. Ceux-ci possĂšdent en effet deux caractĂ©ristiques essentielles: la concurrence et un environnement d'exĂ©cution particuliĂšrement complexe.Nous proposons dans cette thĂšse de rĂ©duire la distance vers la conception d'un tel compilateur vĂ©rifiĂ© en nous concentrant plus spĂ©cifiquement sur la preuve de correction d'un glaneur de cellules concurrent performant. Ce composant de l'environnement d'exĂ©cution prend soin de collecter de maniĂšre automatique la mĂ©moire, en lieu et place du programmeur. Afin de ne pas gĂ©nĂ©rer un ralentissement trop Ă©levĂ© Ă  l'exĂ©cution, le glaneur de cellules doit ĂȘtre extrĂȘmement performant. Plus spĂ©cifiquement, l'algorithme considĂ©rĂ© est dit «au vol»: grĂące Ă  l'usage de concurrence trĂšs fine, il ne cause jamais d'attente active au sein d'un fil utilisateur. La preuve de correction Ă©tablit par consĂ©quent que malgrĂ© l'intrication complexe des fils utilisateurs et du collecteur, ce dernier ne collecte jamais une cellule encore accessible par les premiers. Nous prĂ©sentons dans un premier temps l'algorithme considĂ©rĂ© et sa formalisation en Coq dans une reprĂ©sentation intermĂ©diaire conçue pour l'occasion. Nous introduisons le systĂšme de preuve que nous avons employĂ©, une variante issue de la logique «Rely-Guarantee», et prouvons l'algorithme correct. Raisonner simultanĂ©ment sur l'algorithme de collection et sur l'implantation des structures de donnĂ©es concurrentes manipulĂ©es gĂ©nĂ©rerait une complexitĂ© additionnelle indĂ©sirable. Nous considĂ©rons donc durant la preuve des opĂ©rations abstraites: elles ont lieu instantanĂ©ment. Pour lĂ©gitimer cette simplification, nous introduisons une mĂ©thode inspirĂ©e par les travaux de Vafeiadis et permettant la preuve de raffinement de structures de donnĂ©es concurrentes dites «linĂ©arisables». Nous formalisons l'approche en Coq et la dotons de solides fondations sĂ©mantiques. Cette mĂ©thode est finalement instanciĂ©e sur la principale structure de donnĂ©es utilisĂ©e par le glaneur de cellules

    Formal reasoning about layered monadic interpreters

    No full text
    International audienceMonadic computations built by interpreting, or handling , operations of a free monad are a compelling formalism for modeling language semantics and defining the behaviors of effectful systems. The resulting layered semantics offer the promise of modular reasoning principles based on the equational theory of the underlying monads. However, there are a number of obstacles to using such layered interpreters in practice. With more layers comes more boilerplate and glue code needed to define the monads and interpreters involved. That overhead is compounded by the need to define and justify the relational reasoning principles that characterize the equivalences at each layer. This paper addresses these problems by significantly extending the capabilities of the Coq interaction trees (ITrees) library, which supports layered monadic interpreters. We characterize a rich class of interpretable monads ---obtained by applying monad transformers to ITrees---and show how to generically lift interpreters through them. We also introduce a corresponding framework for relational reasoning about "equivalence of monads up to a relation R". This collection of typeclasses, instances, new reasoning principles, and tactics greatly generalizes the existing theory of the ITree library, eliminating large amounts of unwieldy boilerplate code and dramatically simplifying proofs

    Effectful Programming across Heterogeneous Computations -Work in Progress

    No full text
    International audienceMonadic programming is a popular way to embed effectful computations in purely functional languages. In particular, the so-called free-monad comes with the promise of extensibility and modularity: computations are seen as syntax arising from a signature of operations they may perform. Popularized in a programming context, the approach is nowadays used for verification in proof assistants as well, as witnessed by frameworks such as FreeSpec or Interaction Trees. In this work in progress, we investigate the following question. Can we type each subcomputation with their minimal valid operation signature, and seamlessly combine all these monadic computations of different natures? Furthermore, can we leverage this additional precision in typing to derive monadic invariants for free? We answer positively by suggesting two simple ideas. First, a bind operation between computations living in distinct monads can be defined by transporting them through monad morphisms. Second, to give more structure to the monads we manipulate by indexing them by a semi-lattice as a means to automatically infer the adequate morphisms. We illustrate the benefits on a minimal Coq example: a computation interacting with a memory cell

    Effectful Programming across Heterogeneous Computations -Work in Progress

    No full text
    National audienceMonadic programming is a popular way to embed effectful computations in purely functional languages. In particular, the so-called free-monad comes with the promise of extensibility and modularity: computations are seen as syntax arising from a signature of operations they may perform. Popularized in a programming context, the approach is nowadays used for verification in proof assistants as well, as witnessed by frameworks such as FreeSpec or Interaction Trees. In this work in progress, we investigate the following question. Can we type each subcomputation with their minimal valid operation signature, and seamlessly combine all these monadic computations of different natures? Furthermore, can we leverage this additional precision in typing to derive monadic invariants for free? We answer positively by suggesting two simple ideas. First, a bind operation between computations living in distinct monads can be defined by transporting them through monad morphisms. Second, to give more structure to the monads we manipulate by indexing them by a semi-lattice as a means to automatically infer the adequate morphisms. We illustrate the benefits on a minimal Coq example: a computation interacting with a memory cell

    Effectful Programming across Heterogeneous Computations -Work in Progress

    No full text
    International audienceMonadic programming is a popular way to embed effectful computations in purely functional languages. In particular, the so-called free-monad comes with the promise of extensibility and modularity: computations are seen as syntax arising from a signature of operations they may perform. Popularized in a programming context, the approach is nowadays used for verification in proof assistants as well, as witnessed by frameworks such as FreeSpec or Interaction Trees. In this work in progress, we investigate the following question. Can we type each subcomputation with their minimal valid operation signature, and seamlessly combine all these monadic computations of different natures? Furthermore, can we leverage this additional precision in typing to derive monadic invariants for free? We answer positively by suggesting two simple ideas. First, a bind operation between computations living in distinct monads can be defined by transporting them through monad morphisms. Second, to give more structure to the monads we manipulate by indexing them by a semi-lattice as a means to automatically infer the adequate morphisms. We illustrate the benefits on a minimal Coq example: a computation interacting with a memory cell

    Compilation of Linearizable Data Structures: A Mechanised RG Logic for Semantic Refinement

    Get PDF
    Modern programming languages provide libraries for concurrent data structures. For better performance, these are implemented with fine-grained concurrency. Still, such implementations are linearizable: the programmer can safely assume that they behave atomically. We formalize this insight in Coq as an end-to-end theorem establishing the semantic preservation of a compiler translating abstract, atomic data structures into their concrete, fine-grained concurrent implementation. This embeds the notion of linearizable data structures in a formally verified compiler. At the crux of the proof lies a generic result establishing, once and for all, a simulation relation, starting from a carefully crafted rely-guarantee specification. Inspired by the work of Vafeiadis, implementations are annotated with linearization points, which instrument programs semantics to reflect the behavior of abstract data structures. We successfully applied our generic theorem to concurrent buffers, a data structure used in the implementation of concurrent garbage collectors
    corecore